<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/8/27
 * Time: 14:05
 */

namespace common\services;


use app\common\payment\wxpay\JsApiPay;
use app\common\payment\wxpay\lib\WxPayApi;
use app\common\payment\wxpay\lib\WxPayUnifiedOrder;
use app\common\payment\wxpay\PayNotifyCallBack;
use app\common\payment\wxpay\WxPayConfig;

class WxpayService2
{

    /**
     * 用户下单入口
     * @param $userId 用户id
     * @param $payForIds 订单补充内容
     * @param $amounts 订单金额
     * @param $openid 用户openid
     * @param $type 订单类型
     * @return array
     * @throws \yii\db\Exception
     */
    public function order($userId,$payForIds,$amounts,$openid,$type){
        $trans = \Yii::$app->db->beginTransaction();
        try{
            //下单，调用微信下单接口，返回jsapi所需数据
            //1、生成订单数据
            $order = new SysOrders();
            $order->user_id = $userId;
            $order->order_sn = $this->build_order_no();
            $order->amount = $amounts;
            $order->property_ids = $payForIds;
            $order->order_time = time();
            $order->createed_time = time();
            $order->updated_time = time();
            $order->status = 1;
            $order->type = $type;
            $order->validate()  and $order->save();
            if($order->primaryKey){
                $trans->commit();
                //2、下单
                $goodsInfo['device_info'] = 'WEB';
                $goodsInfo['body'] = '慧聪城-物业缴费';
                $goodsInfo['out_trade_no'] = $order->order_sn;
                $goodsInfo['fee_type'] = 'CNY';
                $goodsInfo['total_fee'] = round($order->amount * 100);//费用单位为分 取整
                $goodsInfo['spbill_create_ip'] = getClientIp();
                $goodsInfo['time_start'] = date("YmdHis");
                $goodsInfo['time_expire'] = date("YmdHis", time() + 600);
                $goodsInfo['trade_type'] = 'JSAPI';
                $goodsInfo['product_id'] = $order->order_sn;
                $goodsInfo['limit_pay'] = 'no_credit';  //是否限制不可使用信用卡支付
                $goodsInfo['openid'] = $openid;
                $res = $this->unifiedOrder($goodsInfo);
                $res['ddd'] = $goodsInfo;
                return $res;
            }
            $trans->rollBack();
            return ['flag'=>400,'msg'=>'下单失败'];
        }catch (\Exception $e){
            $trans->rollBack();
            return ['flag'=>400,'msg'=>$e->getMessage()];
        }
    }

    /**
     * 微信支付回调响应
     */
    public function payNotifyCallBack(){
        try{
            writeLog('开始响应','支付回调信息');
            $config = new WxPayConfig();
            $notify = new PayNotifyCallBack();
            $notify->Handle($config, false);
        }catch (\Exception $e){
            return '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
        }
    }

    /**
     * 实例微信统一下单
     * @param $param
     * @return array
     */
    public function unifiedOrder($param){
        writeLog('进入unifiedOrder','支付下单信息流程--service');
        try{
            $tools = new JsApiPay();
            //②、统一下单
            $input = new WxPayUnifiedOrder();
            $input->SetDevice_info($param['device_info']);//设备号 否
            $input->SetBody($param['body']); //商品描述  是
//            $input->SetDetail($param['device_info']);//商品详情  否
//            $input->SetAttach($param['device_info']);//附加数据  否
            $input->SetOut_trade_no($param['out_trade_no']); //商户订单号 是
            $input->SetFee_type($param['fee_type']);//标价币种 否
            $input->SetTotal_fee($param['total_fee']);//标价金额  是
            $input->SetSpbill_create_ip($param['spbill_create_ip']);// 终端ip 是
            $input->SetTime_start($param['time_start']); //交易起始时间 否
            $input->SetTime_expire($param['time_expire']); //交易结束时间 否
            $input->SetTrade_type($param['trade_type']);//交易类型 是 微信内支付用这个类型
            $input->SetOpenid($param['openid']); //用户标识 否
            $config = new WxPayConfig();
            writeLog($input,'支付下单信息流程--service');
            writeLog($config,'支付下单信息流程--service');
            $order = WxPayApi::unifiedOrder($config, $input);
            if($order['return_code'] == 'SUCCESS'){
                $jsApiParameters = $tools->GetJsApiParameters($order);
                return ['flag'=>1,'msg'=>'下单成功','data'=>json_decode($jsApiParameters,true)];
            }
            return ['flag'=>400,'msg'=>$order['return_msg']];
        }catch (\Exception $e){
            return ['flag'=>400,'msg'=>$e->getMessage()];
        }
    }

    /**
     * 支付回调业务处理方法
     * @param $data
     * @return bool
     * @throws \yii\db\Exception
     */
    public function payCallbackDeal($data){
        writeLog('进入payCallbackDeal方法','支付回调信息');
        $trans = \Yii::$app->db->beginTransaction();
        try{
            //根据订单号查询数据
            $orderInfo = SysOrders::find()->where(['order_sn'=>$data['out_trade_no']])->andWhere(['!=','status',2])->one();
            if(!$orderInfo){
                writeLog('没找到对应的订单信息','支付回调信息');
                return true; //没找到合适 无需操作
            }
            if(round($orderInfo->amount * 100) != $data['total_fee']){ //金额没匹配上
                writeLog('金额没匹配上','支付回调信息');
                return false;
            }
            $orderInfo->status = 2;
            $orderInfo->updated_time = time();
            $orderInfo->save();
            //增加记录，将对应的缴费信息给更新为已缴费
            $payLog = new SysOrderPaymentLog();
            $payLog->order_sn = $orderInfo->order_sn;
            $payLog->order_id = $orderInfo->order_id;
            $payLog->pay_code = $data['transaction_id'];
            $payLog->amount = $data['total_fee']/100;
            $payLog->status = 3;
            $payLog->callback_time =time();
            $payLog->create_time = time();
            $payLog->update_time = time();
            $payLog->callback_info = json_encode($data);
            $payLog->pay_time = strtotime($data['time_end']);
            $payLog->save();

            //根据订单类型判断，处理哪种类型的业务
            switch (intval($orderInfo->type)){
                case 1 : //物业缴费
                    SysClientProperty::updateAll(['is_pay'=>1,'pay_time'=>strtotime($data['time_end'])],['id'=>$orderInfo->property_ids]);
//                    SysPropertyPayment::updateAll(['is_pay'=>1,'pay_time'=>strtotime($data['time_end'])],['pay_id'=>$ids]);
                    break;
                case 2 ://维修付费
                    SysReservationService::updateAll(['service_state'=>4,'pay_time'=>strtotime($data['time_end'])],['service_id'=>$orderInfo->property_ids]);
                    break;
            }

            if($orderInfo->primaryKey && $payLog->primaryKey){
                writeLog('支付回调处理成功','支付回调信息');
                $trans->commit();return true;
            }
            writeLog('支付回调处理失败','支付回调信息');
            $trans->rollBack();return false;
        }catch (\Exception $e){
            writeLog('业务逻辑执行错误','支付回调信息');
            writeLog($e->getMessage(),'支付回调信息');
            $trans->rollBack();
            return false;
        }
    }


    /**
     *生成订单号
     * uniqid - 官方是这样说的：
     * Gets a prefixed unique identifier based on the current time in microseconds.
     */
    function build_order_no()
    {
        return 'JDC'.date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
    }
}